# ======================================================================
#
# Copyright (C) ADN
# ADN::LIBRARY::ADAPTERS::CISCO::IOS::Connect Connect.pm
# Description:
#  - Gestion des connexions (Cisco IOS)
#
# ======================================================================

package ADN::LIBRARY::ADAPTERS::CISCO::IOS::Connect;

use strict;

use ADN::LIBRARY::ADAPTERS::Protocol;

# #######################
# CREATE OBJECT
# #######################
sub new
{
	# Construction de l'objet $self
	my $self = shift;
	my $class = ref($self) || $self;
	return $self if ref $self;
	$self = bless {} => $class;
	$self->{enable} = 0;
	$self->{credential_boucle} = 0;
	$self->{ok_send_username} = 0;
	$self->{lancer} = ADN::LIBRARY::ADAPTERS::Protocol->new();
	return $self;
}

# #######################
# MAIN
# #######################
sub start
{
  my $self = shift;
  my $verif;
  ( $self->{host}, $self->{credential}, $self->{protocol}, $verif ) = @_;

  if ($self->_connect()) {
    $self->distribut();
    if (defined($self->{connexion}) && defined($self->{connexion})) {
    	return ($self->{connexion}, $self->{prompt}) if (!defined $verif);
    	return ($self->{connexion}, $self->{prompt}, $self->{line_enable}) if (defined $verif);
		}
  }
  return (undef, undef) if (!defined $verif);
  return (undef, undef, undef) if (defined $verif);
  return;
}

# #######################
# CONNECT TO EQUIPEMENT
# #######################
sub _connect
{
	my $self = shift;
	my $ref;

	if (defined($self->{connexion})) {
  	($self->{connexion}, $ref, $self->{protocol}) = $self->{lancer}->start($self->{host}, 
																																					 $self->{credential}, 
																																					 $self->{protocol}, 
																																					 $self->{connexion});
	} else {
		($self->{connexion}, $ref, $self->{protocol}) = $self->{lancer}->start($self->{host}, 
																																					 $self->{credential}, 
																																					 $self->{protocol}, 
																																					 undef);
	}
	if (defined($ref) && defined($self->{connexion})) {
  	%{$self->{hash_credential}} = %$ref;
    return 1;
  }
  return 0;
}

# #######################
# FUNCTION DISTRIBUT
# #######################
sub distribut
{
    my $self = shift;
    my ($nbr, $compare);
    my (@compare, @function);

    push @compare, '[uU]sername[:]?|^[lL]ogin[:]?|[iI]dentifiant[:]?';
    push @compare, '[pP]assword[:]?';
    push @compare, '[lL]ogin\sinvalid';
    push @compare, '[\#\>]\s*$';

    push @function, \&send_username;
    push @function, \&send_password;
    push @function, \&reconnect;
    push @function, \&mode_enable;

    $self->{line} = $self->{connexion}->get_lastline(0.5);
    $nbr = 0;
    foreach my $compare (@compare)
    {
        if (($self->{line} =~ /$compare/smx) && ($self->is_enable() == 0))
        {
          $function[$nbr]($self);
        }
        $nbr++;
    }
    @compare = @function = undef;
    $nbr = $compare = undef;
    return;
}

# #######################
# SEND USERNAME
# #######################
sub send_username
{
  my ($self) = @_;
  my $output = 1;

	if ($self->{credential_boucle} > 0) {
    $output = $self->_connect();
	}
	if ($output) {
 		$self->{connexion}->send($self->{hash_credential}{username}, 1);
 		$self->{credential_boucle}++;
 		$self->{ok_send_username} = 1;
 		$self->distribut();
	}
	return;
}

# #######################
# SEND PASSWORD
# #######################
sub send_password
{
  my ($self) = @_;
  my $output = 1;

	if (($self->{credential_boucle} > 0) && ($self->{ok_send_username} == 0)) {
    $output = $self->_connect();
	}
	if ($output) {
    $self->{connexion}->send($self->{hash_credential}{password}, 1);
    $self->{credential_boucle}++;
    $self->distribut();
  }
  return;
}

# #######################
# SUPER USER
# #######################
sub mode_enable
{
  my ($self) = @_;
  my $line;

  if (defined($self->{connexion})) {
    if ($self->{line} =~ /[\>]\s*$/smx)
    {
      $self->{connexion}->send("enable", 1);
      $self->{line_enable} = $self->{connexion}->get_lastline(0.5);
      if ($self->{line_enable} =~ /[pP]assword[:]?/smx) {
        $self->{connexion}->send($self->{hash_credential}{enable}, 1);
        $self->{line_enable} = $self->{connexion}->get_lastline(0.5);
        if ($self->{line_enable} =~ /[pP]assword[:]?/smx) {
          $self->calcul_prompt(undef, $self->{line_enable});
        }
        else {
          $self->{enable} = 1;
          $self->calcul_prompt(undef, $self->{line_enable});
        }
      }
      else {
        $self->calcul_prompt(undef, $self->{line_enable});
      }
    }
    elsif ($self->{line} =~ /[\#]\s*$/smx) {
      $self->{enable} = 1;
      $self->calcul_prompt(undef, $self->{line});
    }
  }
  undef $line;
  return;
}

# #######################
# PROMPT
# #######################
sub calcul_prompt
{
  my $self = shift;

  if (defined($self->{connexion})) {
    $self->{prompt} = $self->{connexion}->calcul_prompt($_[0], $_[1]);
  }
  return;
}

# #######################
# ENABLE TRUE/FALSE
# #######################
sub is_enable
{
  my $self = shift;

  if ($self->{enable} == 1)
  {
    return 1;
  }
  return undef;
}

# #######################
# DESTROY OBJECT
# #######################
sub DESTROY {
	my $self = shift;
	return;
}
1;
__END__
